<?php

/**
 * Build forms for creating/editing exercises
 *
 * PHP version 5
 *
 * LICENSE: This source file is subject to the MIT License, available
 * at http://www.opensource.org/licenses/mit-license.html
 *
 * @author     Jayson Schmidt <jayson@888mobileapps.com>
 * @copyright  2013 888MobileApps
 * @license    http://www.opensource.org/licenses/mit-license.html
 */

class Exercise_builder extends DB_Connect {

	public function __construct($dbo=NULL) {
		parent::__construct($dbo);
	}
	
	/*
	 * Loads data into an array
	 *
	 * @param String $dataType the name of the table to select from
	 * @param int $pid an optional PID to filter results
	 * @return array an array of data from the database
	 */
	 
	private function _loadDataSet($dataType, $pid=NULL){
		
		if(!empty($pid))
			$where = " WHERE pid=:pid";

		try {
			$stmt = $this->db->prepare("SELECT * FROM ".$dataType.$where);
			if(!empty($pid))
				$stmt->bindParam(":pid", $pid, PDO::PARAM_STR);
			$stmt->execute();
			$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
			$stmt->closeCursor();
			
			return $results;
		
		}catch (Exception $e) {
			die($e->getMessage());
		}
	
	}
	
	/*
	 * Loads exercises into an array. If $pid is supplied, will
	 * only load the specified exercise.
	 *
	 * @param int $pid The id of the exercise to load
	 * @return array exercise info
	 */
	 
	private function _createObj($dataType, $pid=NULL) {
		
		$arr = $this->_loadDataSet($dataType, $pid);

		$class = ucfirst($dataType);
		
		$dataSet = array();
		foreach($arr as $data) {
			try {
				$dataSet[] = new $class($data);
			}catch (Exception $e) {
				die($e->getMessage());
			
			}
			
		}
		
		return $dataSet;
	}

	public function displayForm() {
		
		
		/*
		 * Create lists of all exercises, all types, and all muscles
		 */
		$exList = $this->_createObj('exercise');
		$typeList = $this->_createObj('target_type');
		$muscList = $this->_createObj('muscle');
		
		/*
		 * Check to see if an exercise_id is present; 
		 * if it is, then load $id with the exercise_id
		 * and sanitize it by casting to int.
		 */
		if(isset($_GET['exercise_id'])) {
			$id = (int) $_GET['exercise_id'];
			
		}else {
			$id = NULL;
		}
		
		$submit = 'Create new exercise';
		$action = 'create_exercise';
		
		if(!empty($id)) {
			
			$exercise = array_shift($this->_createObj('exercise',$id));
			
			if(!is_object($exercise)){ return NULL; }
		
			$submit = 'Edit this exercise';
			$action = 'update_exercise';
			
			$targetMuscles = array();
			
			/*
			 * Build arrays of muscules targeted for each target type (primary, secondary, etc)
			 */
			foreach($typeList as $tkey=>$tvalue){
			
				$sql = "SELECT `muscle`.`pid`, `muscle`.`muscle_name`, `exercise_target`.`pid`
						FROM `muscle` 
						INNER JOIN `exercise_target`
						ON `exercise_target`.`muscle_id` = `muscle`.`pid`
						INNER JOIN `exercise`
						ON `exercise_target`.`exercise_id` = `exercise`.`pid`
						WHERE `exercise_target`.`target_type` = '".$tvalue->_id."'
						AND `exercise_target`.`exercise_id` = '".$id."'";
						
				$stmt = $this->db->prepare($sql);
				$stmt->execute();
				$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
				$stmt->closeCursor();
				
				$targetMuscles[$tvalue->_id] = $results;
				
				if(!empty($targetMuscles)) {
					$targetString .= '<div>'.strtoupper($tvalue->_type).'</div>';
					foreach($results as $key=>$value) {
						/**
						 * Each selector is identified by the name exercise_target.<excercise_target.pid>
						 * where <exercise_target.pid> is the pid of the exercise to be updated
						 * The value passed in $_POST is the pid of the muscle to be updated in 
						 * exercise_target
						 */
						$targetString .= '<div><select name="exercise_target.'.$value['pid'].'">';
						foreach($muscList as $mkey=>$mvalue) {
							if($mvalue->_name == $value['muscle_name'])
								$targetString .= '<option selected value="'.$mvalue->_id.'">'.$mvalue->_name.'</option>';
							else
								$targetString .= '<option value="'.$mvalue->_id.'">'.$mvalue->_name.'</option>';
						
						}
						$targetString .= '</select>
						<input type="checkbox" name="delete_item.'.$value['pid'].'" value="'.$value['pid'].'" />
						</div>';
					}
									
				}
			
			}
			
			/*
			 * Generate the form to add targeted muscles.
			 */
			$addItemString = '';
			foreach($typeList as $tkey=>$tvalue) {
				$addItemString .= '
				<div>
					<form action="/workout/inc/process.inc.php" method="POST">
						<input type="hidden" name="target_type" value="'.$tvalue->_id.'" />
						<input type="hidden" name="action" value="add_item" />
						<input type="hidden" name="token" value="'.$_SESSION['token'].'" />
						<input type="hidden" name="exercise_id" value="'.$_GET['exercise_id'].'" />
						<input type="submit" value="Add '.$tvalue->_type.' target" />
					</form>
				</div>';
			
			}
			
			$deleteItemString = '<input type="submit" name="submit" value="Delete Checked" />';
					
		}		
		 
		 $editString = 
		 '<div>Load exercise</div>
		 <div>
			 <form action="/workout/exercise_builder.php" method="GET">
				<select name="exercise_id">';
					foreach($exList as $key=>$value){
						if($value->_id == $_GET['exercise_id'])
							$editString .= '<option selected value="'.$value->_id.'">'.$value->_name.'</option>';
						else
							$editString .= '<option value="'.$value->_id.'">'.$value->_name.'</option>';
					}
					$editString .=
				'</select>
				<input type="submit" value="Load Exercise" />
			 </form>
			 <form action="/workout/inc/process.inc.php" method="POST">
			 	<input type="hidden" name="action" value="create_exercise" />
				<input type="hidden" name="token" value="'.$_SESSION['token'].'" />
			 	<input type="submit" value="Create new Exercise" />
			 </form>
		 </div>';
		
		/*
		 * Populate description, setup, inhale, exhale and notes information
		 *
		 * Because of the naming coventions used in the db, these selections have
		 * to be made individualy. Because this is such a low use admin tool, I 
		 * see no reason to spend the time in implementing a more efficient methodology.
		 */
		$selections = array(0=>'pid',1=>'description');
		$criteria = array('exercise_id'=>$_GET['exercise_id']); 
		$results = Utility::selectByArray($this->db, 'exercise_description', $selections, $criteria); 
		$description = array_shift($results);
		
		$selections = array(0=>'pid',1=>'description');
		$criteria = array('exercise_id'=>$_GET['exercise_id']); 
		$results = Utility::selectByArray($this->db, 'exercise_setup', $selections, $criteria); 
		$setup = array_shift($results);
		
		$selections = array(0=>'pid',1=>'description');
		$criteria = array('exercise_id'=>$_GET['exercise_id']); 
		$results = Utility::selectByArray($this->db, 'exercise_inhale_movement', $selections, $criteria); 
		$inhale = array_shift($results);
		
		$selections = array(0=>'pid',1=>'description');
		$criteria = array('exercise_id'=>$_GET['exercise_id']); 
		$results = Utility::selectByArray($this->db, 'exercise_exhale_movement', $selections, $criteria); 
		$exhale = array_shift($results);
		
		$selections = array(0=>'pid',1=>'note');
		$criteria = array('exercise_id'=>$_GET['exercise_id']); 
		$results = Utility::selectByArray($this->db, 'exercise_note', $selections, $criteria); 
		$note = array_shift($results);

		$descriptionString = '<div>
								<div>
									Description
								</div>
								<input type="hidden" name="description_id" value="'.$description['pid'].'" />
								<textarea name="description">'.$description['description'].'</textarea>
							</div>';
								
		$setupString = '<div>
							<div>
								Setup
							</div>
							<input type="hidden" name="setup_id" value="'.$setup['pid'].'" />
							<textarea name="setup">'.$setup['description'].'</textarea>
						</div>';			
					
		$inhaleString = '<div>
							<div>
								Inhale Movement
							</div>
							<input type="hidden" name="inhale_id" value="'.$inhale['pid'].'" />
							<textarea name="inhale">'.$inhale['description'].'</textarea>
						</div>';
		
		$exhaleString = '<div>
							<div>
								Exhale Movement
							</div>
							<input type="hidden" name="exhale_id" value="'.$exhale['pid'].'" />
							<textarea name="exhale">'.$exhale['description'].'</textarea>
						</div>';
					
		$noteString = '<div>
							<div>
								Note
							</div>
							<input type="hidden" name="note_id" value="'.$note['pid'].'" />
							<textarea name="note">'.$note['note'].'</textarea>
						</div>';
		 
		/*
		 * Create new exercise
		 */
		$createString = 
		'<div>'.$submit.'</div>
		<div>
			<form action="/workout/inc/process.inc.php" method="POST">
				<input type="hidden" name="action" value="'.$action.'" />
				<input type="hidden" name="token" value="'.$_SESSION['token'].'" />
				<input type="hidden" name="exercise_id" value="'.$_GET['exercise_id'].'" />
				<input type="text" name="exercise_name" value="'.$exercise->_name.'" />';
				$createString .= $targetString.
								 $descriptionString.
								 $setupString.
								 $inhaleString.
								 $exhaleString.
								 $noteString;
				$createString .='
				<input type="submit" name="submit" value="'.$submit.'" />';
				$createString .= $deleteItemString;
				$createString .='
			</form>
		</div>';
	
		return $editString.$createString.$addItemString;
		
	}
	
	/*
	 * Validates the form and creates an exercise
	 *
	 * @return mixed TRUE on success, an error message on failure
	 */
	public function createExercise() {
		
		if($_POST['action']!='create_exercise') {
			return "The method createExercise was accessed incorrectly";
		}
		
		if(!empty($_POST['exercise_name']))	
			$name = $_POST['exercise_name'];
		else
			$name = 'New Exercise';
			
		$name = htmlentities($name, ENT_QUOTES);
		
		$sql = "INSERT INTO `exercise` 
						(`exercise_name`) VALUES (:name)";
						
		
		try {
			$stmt = $this->db->prepare($sql);
			$stmt->bindParam(":name", $name, PDO::PARAM_STR);
			$stmt->execute();
			$insertId = $this->db->lastInsertId();
			$stmt->closeCursor();			
		}catch (Exception $e) {
			return $e->getMessage();
		}

		$sql = "INSERT INTO `exercise_description`
							(`exercise_id`) VALUES (:id)";
							
		try {
			$stmt = $this->db->prepare($sql);
			$stmt->bindParam(":id", $insertId, PDO::PARAM_STR);
			$stmt->execute();
			$stmt->closeCursor();			
		}catch (Exception $e) {
			return $e->getMessage();
		}
		
		$sql = "INSERT INTO `exercise_setup`
							(`exercise_id`) VALUES (:id)";
							
		try {
			$stmt = $this->db->prepare($sql);
			$stmt->bindParam(":id", $insertId, PDO::PARAM_STR);
			$stmt->execute();
			$stmt->closeCursor();			
		}catch (Exception $e) {
			return $e->getMessage();
		}
		
		$sql = "INSERT INTO `exercise_inhale_movement`
							(`exercise_id`) VALUES (:id)";
							
		try {
			$stmt = $this->db->prepare($sql);
			$stmt->bindParam(":id", $insertId, PDO::PARAM_STR);
			$stmt->execute();
			$stmt->closeCursor();			
		}catch (Exception $e) {
			return $e->getMessage();
		}
		
		$sql = "INSERT INTO `exercise_exhale_movement`
							(`exercise_id`) VALUES (:id)";
							
		try {
			$stmt = $this->db->prepare($sql);
			$stmt->bindParam(":id", $insertId, PDO::PARAM_STR);
			$stmt->execute();
			$stmt->closeCursor();			
		}catch (Exception $e) {
			return $e->getMessage();
		}
		
		$sql = "INSERT INTO `exercise_note`
							(`exercise_id`) VALUES (:id)";
							
		try {
			$stmt = $this->db->prepare($sql);
			$stmt->bindParam(":id", $insertId, PDO::PARAM_STR);
			$stmt->execute();
			$stmt->closeCursor();
			return TRUE;			
		}catch (Exception $e) {
			return $e->getMessage();
		}
	
	}	
	
	/*
	 * Validates the form and updates an exercise
	 *
	 * @return mixed TRUE on success, an error message on failure
	 */
	public function updateExercise() {
		
		if($_POST['action']!='update_exercise') {
			return "The method updateExercise was accessed incorrectly";
		}
		
		if(empty($_POST['exercise_id'])) {
			return "Invalid id supplied to updateExercise";
		
		}
		
		$updates = array();
		
		foreach($_POST as $key=>$value) {
			if(strpos($key, 'exercise_target') !== FALSE) {
				$updates[substr($key, strrpos($key,'_')+1)] = $value;
			}
		}
		
		// Update exercise name
		Utility::updateByPid($this->db, 'exercise', 'exercise_name', $_POST['exercise_id'], $_POST['exercise_name']);
		
		// Update target muscles
		Utility::updateByArray($this->db, 'exercise_target', 'muscle_id', $criteria, $updates);
		
		// Update exercise description
		Utility::updateByPid($this->db, 'exercise_description', 'description', $_POST['description_id'], $_POST['description']);
		
		// Update exercise setup
		Utility::updateByPid($this->db, 'exercise_setup', 'description', $_POST['setup_id'], $_POST['setup']);
		
		// Update exercise inhale movement
		Utility::updateByPid($this->db, 'exercise_inhale_movement', 'description', $_POST['inhale_id'], $_POST['inhale']);
		
		// Update exercise exhale
		Utility::updateByPid($this->db, 'exercise_exhale_movement', 'description', $_POST['exhale_id'], $_POST['exhale']);
		
		// Update exercuse note
		Utility::updateByPid($this->db, 'exercise_note', 'note', $_POST['note_id'], $_POST['note']);
		
		return TRUE;
		
	}
	
	/*
	 * Validates the form and deletes an exercises
	 *
	 * @return mixed TRUE on success, an error message on failure
	 */
	public function deleteExercise() {
		if($_POST['action']!='delete_exercise') {
			return "The method deleteExercise was accessed incorrectly";
		}
		
		
		
	}
	
	/*
	 * Validates the form and adds an item to the specified target type
	 *
	 * @return mixed TRUE on success, an error message on failure
	 */
	public function addItem() {
		if($_POST['action']!='add_item') {
			return "The method addItem was accessed incorrectly";
		}
		
		/*
		 * Default muscle_id = 1
		 */
		$sql = "INSERT INTO 
					`exercise_target`
					(`exercise_id`, `target_type`)
				VALUES
					(:exercise_id, :target_type)";
					
		/*
		 * Cast to int for security
		 */
		$eid = (int)$_POST['exercise_id'];
		$tt = (int)$_POST['target_type'];
		
		try {
			$stmt = $this->db->prepare($sql);
			$stmt->bindParam(":exercise_id", $eid, PDO::PARAM_INT);
			$stmt->bindParam(":target_type", $tt, PDO::PARAM_INT);
			$stmt->execute();
			$stmt->closeCursor();
			return TRUE;
		}catch (Exception $e) {
			return $e->getMessage();
		}
		
	}
	
	/*
	 * Validates the form and deletes an item
	 *
	 * @return mixed TRUE on success, an error message on failure
	 */
	public function deleteItem() {
		if($_POST['action']!='delete_item') {
			return "The method deleteItem was accessed incorrectly";
		}
		
		$deletes = array();
		
		foreach($_POST as $key=>$value) {
			if(strpos($key, 'delete_item') !== FALSE) {
				$deletes[] = $value;
			}
		}
		
		$sql = "DELETE FROM
					`exercise_target`
				WHERE
					`exercise_target`.`pid` = :tid";
		
		try {
			
			$stmt = $this->db->prepare($sql);
			
			foreach($deletes as $key=>$value) {
				
				$tid = (int)$value;
			
				$stmt->bindParam(":tid", $tid, PDO::PARAM_INT);
				$stmt->execute();
			}

			$stmt->closeCursor();
			return TRUE;
		}catch (Exception $e) {
			return $e->getMessage();
		}
		
	}

}

?>